package com.robosense.datacenter.dynamic.datasource;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 对指定文件夹下Java类中中方法进行切面拦截
 * 获取方法上的信息，进行逻辑处理
 */
@Component
@Aspect
@Order(-100)
@Slf4j
public class DataSourceSwitchAspect {

    @Pointcut("execution(* com.robosense.datacenter.biz.center.service.impl..*.*(..))")
    private void center() {
    }

    @Pointcut("execution(* com.robosense.datacenter.biz.guard.service.*.*(..))")
//    @Pointcut("execution(* com.robosense.datacenter.biz.guard.service.impl..*.*(..))")
    private void guard() {
    }

    @Before( "center()" )
    public void center(JoinPoint joinPoint) {
        log.info("切换到====================db1 数据源...");
        setDataSource(joinPoint,DBTypeEnum.center);
    }

    @Before("guard()" )
    public void guard (JoinPoint joinPoint) {
        log.info("切换到====================db2 数据源...");
        setDataSource(joinPoint,DBTypeEnum.guard);
    }

    //后置通知是不管有没有异常,一定会执行
    @After("guard()||center()")
    public void clearDB () {
        DbContextHolder.clearDbType();
    }


    // 添加注解方式,如果有注解优先注解,没有则按传过来的数据源配置
    private void setDataSource(JoinPoint joinPoint, DBTypeEnum dbTypeEnum) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        DataSourceSwitch dataSourceSwitch = methodSignature.getMethod().getAnnotation(DataSourceSwitch.class);
        if (Objects.isNull(dataSourceSwitch)) {
            log.error("根据默认数据源,注解值为:"+dbTypeEnum);
            DbContextHolder.setDbType(dbTypeEnum);
        }else{
            dataSourceSwitch.value();
            log.error("根据注解来切换数据源,注解值为:"+dataSourceSwitch.value());
            switch (dataSourceSwitch.value().getValue()) {
                case "center":
                    DbContextHolder.setDbType(DBTypeEnum.center);
                    break;
                case "guard":
                    DbContextHolder.setDbType(DBTypeEnum.guard);
                    break;
                default:
                    DbContextHolder.setDbType(dbTypeEnum);
            }
        }
    }
}
